// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   KeelRuntime.java

package keel.runtime;

import backstage.runtime.ApplicationClassLoader;
import backstage.runtime.KeelRuntimeImpl;
import java.awt.Image;
import java.io.IOException;
import java.io.PrintStream;
import java.util.*;

import javax.media.opengl.GLProfile;

import keel.gfx.*;
import keel.resource.ArchiveClassLoader;
import keel.runtime.audio.AudioPlayer;
import keel.runtime.ctrl.ControllerDescriptor;
import keel.runtime.ctrl.ControllerPort;
import keel.runtime.ctrl.ControllerPortManager;
import keel.runtime.ctrl.KeyboardDevice;
import keel.runtime.event.ControllerListener;
import keel.runtime.event.Event;
import keel.runtime.event.EventMulticaster;
import keel.runtime.event.InputMethodEvent;
import keel.runtime.event.InputMethodListener;
import keel.runtime.event.KeyEvent;
import keel.runtime.event.KeyListener;
import keel.runtime.event.MouseEvent;
import keel.runtime.event.MouseListener;
import keel.runtime.im.ActiveInputMethodRequests;
import keel.runtime.im.PassiveInputMethodRequests;

// Referenced classes of package keel.runtime:
//            Application, DisplayMode, Cursor

public abstract class KeelRuntime
{

    static void initKeelRuntime()
    {
        try
        {
            resources = ResourceBundle.getBundle("backstage.resources.runtime", Locale.getDefault(), keel.runtime.KeelRuntime.class.getClassLoader());
//            String os = System.getProperty("os.name");
//            if(os.startsWith("Wind"))
//                ostype = "backstage.runtime.KeelRuntimeWindowsImpl";
//            else
//            if(os.startsWith("Mac OS X"))
//            {
//                ostype = "backstage.runtime.KeelRuntimeMacOSXImpl";
//            } else
//            {
                ostype = "backstage.runtime.KeelRuntimeSWTImpl";
//                throw new Exception("no surpported Platform");
//            }
            Class c = Class.forName(ostype);
            runtime = (KeelRuntime)c.newInstance();
        }
        catch(Throwable t)
        {
            t.printStackTrace();
            System.exit(1);
        }
    }

    protected KeelRuntime()
    {
        keyListener = null;
        mouseListener = null;
        inputMethodListener = null;
        application = null;
        init();
    }

    public static void main(String args[])
    {
        initKeelRuntime();
        if(runtime == null)
        {
            System.out.println("no surpported Platform");
            System.exit(1);
        }
        String appClassName = null;
        String appPaths[] = (String[])null;
        String appArgs[] = (String[])null;
        for(int i = 0; i < args.length; i++)
        {
            if(args[i].startsWith("-") && i + 1 < args.length)
            {
                if(args[i].equals("-entrypath"))
                {
                    StringTokenizer pathTokenizer = new StringTokenizer(args[++i], System.getProperty("path.separator"));
                    appPaths = new String[pathTokenizer.countTokens()];
                    for(int j = 0; pathTokenizer.hasMoreTokens(); j++)
                        appPaths[j] = pathTokenizer.nextToken();

                } else
                if(args[i].equals("-debug"))
                    GLContext.setDebugEnabled(true);
                continue;
            }
            appClassName = args[i++];
            appArgs = new String[args.length - i];
            System.arraycopy(args, i, appArgs, 0, appArgs.length);
            break;
        }

        if(appClassName == null)
        {
            System.out.println("Usage: KeelRuntime [-options] class [args...]");
            System.out.println("where options include:");
            System.out.println("-debug     debug graphics code");
            System.out.println("-entrypath <path or jar files...>");
            System.out.println("           set search path for keel application classes");
            System.exit(1);
        }
        if(appPaths == null)
            appPaths = (new String[] {
                "."
            });
        if(appArgs == null)
            appArgs = new String[0];
        appClassName = appClassName.replace('/', '.');
        runtime.createClassLoader(appClassName, appPaths);
        boolean valid = ((KeelRuntimeImpl)runtime).initRuntime();
        if(!valid)
            runtime.exitWithFatalError(resources.getString("FatalError.InvalidRuntime"));
        do
        {
            restartRequested = false;
            try
            {
                runtime.startApplication(appArgs);
            }
            catch(Exception e)
            {
                System.err.println("Exception in KeelRuntime.main:");
                e.printStackTrace();
            }
            catch(Throwable e)
            {
                System.err.println("Error in KeelRuntime.main:");
                e.printStackTrace();
            }
            if(restartRequested)
                runtime.restartApplication();
            else
                return;
        } while(true);
    }

    public void restart()
    {
        restartRequested = true;
    }

    void createClassLoader(String appClassName, String appPaths[])
    {
        classLoader = new ApplicationClassLoader(appClassName);
        for(int i = 0; i < appPaths.length; i++)
        {
            String path = appPaths[i];
            try
            {
                classLoader.openArchive(path);
            }
            catch(IOException e)
            {
                System.err.println("Invalid archive path: " + path);
                e.printStackTrace();
                System.exit(1);
            }
        }

    }

    void startApplication(String appArgs[])
        throws Exception
    {
        Thread.currentThread().setContextClassLoader(classLoader);
        Class entryClass = Class.forName(classLoader.getAppClassName(), true, classLoader);
        application = (Application)entryClass.newInstance();
        try
        {
            application.keelMain(runtime, appArgs);
        }
        catch(Exception e)
        {
            System.err.println("Exception in Application#keelMain:");
            e.printStackTrace();
        }
    }

    void restartApplication()
    {
        disposeDisplay();
        init();
        stop();
        classLoader = new ApplicationClassLoader(classLoader);
        System.gc();
        System.runFinalization();
    }

    public ArchiveClassLoader getClassLoader()
    {
        return classLoader;
    }

    protected void init()
    {
        keyListener = null;
        mouseListener = null;
        inputMethodListener = null;
        enableInputMethods(true);
        setInputMethodPassiveMode();
    }

    public static final KeelRuntime getRuntime()
    {
        return runtime;
    }

    public abstract void repaint();

    public abstract void exitWithFatalError(String s);

    public abstract void setAutoUpdate(boolean flag);

    public abstract boolean isAutoUpdate();

    public void addKeyListener(KeyListener listener)
    {
        keyListener = EventMulticaster.add(keyListener, listener);
    }

    public void removeKeyListener(KeyListener listener)
    {
        keyListener = EventMulticaster.remove(keyListener, listener);
    }

    public void addMouseListener(MouseListener listener)
    {
        mouseListener = EventMulticaster.add(mouseListener, listener);
    }

    public void removeMouseListener(MouseListener listener)
    {
        mouseListener = EventMulticaster.remove(mouseListener, listener);
    }

    public void addInputMethodListener(InputMethodListener listener)
    {
        inputMethodListener = EventMulticaster.add(inputMethodListener, listener);
    }

    public void removeInputMethodListener(InputMethodListener listener)
    {
        inputMethodListener = EventMulticaster.remove(inputMethodListener, listener);
    }

    protected void processKeyEvent(KeyEvent e)
    {
        if(keyListener == null)
            return;
        switch(e.getID())
        {
        case 401: 
            keyListener.keyPressed(e);
            break;

        case 402: 
            keyListener.keyReleased(e);
            break;

        case 400: 
            keyListener.keyTyped(e);
            break;
        }
    }

    protected void processMouseEvent(MouseEvent e)
    {
        if(mouseListener == null)
            return;
        switch(e.getID())
        {
        case 500: 
            mouseListener.mouseClicked(e);
            break;

        case 501: 
            mouseListener.mousePressed(e);
            break;

        case 502: 
            mouseListener.mouseReleased(e);
            break;

        case 505: 
            mouseListener.mouseWheelMoved(e);
            break;

        case 503: 
            mouseListener.mouseMoved(e);
            break;

        case 504: 
            mouseListener.mouseDragged(e);
            break;

        case 506: 
            mouseListener.mouseEntered(e);
            break;

        case 507: 
            mouseListener.mouseExited(e);
            break;
        }
    }

    protected void processInputMethodEvent(InputMethodEvent e)
    {
        if(inputMethodListener == null)
            return;
        switch(e.getID())
        {
        case 1100: 
            inputMethodListener.textChanged(e);
            break;
        }
    }

    public abstract void run();

    public abstract Event peekEvent();

    public abstract void postEvent(Event event);

    public void processEvent(Event event)
    {
        if(event instanceof KeyEvent)
            processKeyEvent((KeyEvent)event);
        else
        if(event instanceof MouseEvent)
            processMouseEvent((MouseEvent)event);
        else
        if(event instanceof InputMethodEvent)
            processInputMethodEvent((InputMethodEvent)event);
    }

    public abstract void stop();

    public abstract DisplayMode[] getDisplayModeList();

    public PixelFormat getDefaultPixelFormat()
    {
        PixelFormat pixelFormats[] = getPixelFormatList();
        if(pixelFormats.length == 0)
            return null;
        int index = 0;
        int maxPoint = 0;
        for(int i = 0; i < pixelFormats.length; i++)
        {
            int point = 0;
            if(pixelFormats[i].getDepthBits() > 0)
            {
                point = 100;
                if(pixelFormats[i].getStencilBits() > 0)
                    point -= 30;
                if(pixelFormats[i].getAlphaBits() > 0)
                    point -= 40;
            }
            if(point > maxPoint)
            {
                maxPoint = point;
                index = i;
            }
        }

        return pixelFormats[index];
    }

    public void createGraphicsWithDefaultPixelFormat()
    {
        PixelFormat pf = getDefaultPixelFormat();
        if(pf == null)
            exitWithFatalError(resources.getString("FatalError.PixelFormat"));
        createGraphics(pf);
    }

    public PixelFormat[] getPixelFormatList()
    {
        return getPixelFormatList(1);
    }

    public abstract PixelFormat[] getPixelFormatList(int i);

    public abstract int getWidth();

    public abstract int getHeight();

    public abstract boolean isWindowMode();

    public void createWindow(int width, int height)
    {
        createWindow("", width, height);
    }

    public abstract void createWindow(String s, int i, int j);

    public abstract boolean isDisplayAvailable(DisplayMode displaymode);

    public abstract void createDisplay(DisplayMode displaymode);

    public abstract void createGraphics(PixelFormat pixelformat);

    public abstract void disposeDisplay();

    public abstract GLGraphics getGraphics();

    public abstract boolean isGraphicsActive();

    public abstract void yield();

    public abstract boolean isForeProcess();

    public void setVSync(boolean flag)
    {
    }

    public abstract void setCursorVisible(boolean flag);

    public abstract void setIconImage(Image image);

    public abstract void enableInputMethods(boolean flag);

    public void setInputMethodPassiveMode()
    {
        setInputMethodPassiveMode(null, true);
    }

    public abstract void setInputMethodPassiveMode(PassiveInputMethodRequests passiveinputmethodrequests, boolean flag);

    public abstract boolean setInputMethodActiveMode(ActiveInputMethodRequests activeinputmethodrequests);

    public abstract void useController(int i, ControllerDescriptor controllerdescriptor, int j, boolean flag);

    public void useController(int numPorts, ControllerDescriptor descriptor)
    {
        if(descriptor == null)
        {
            throw new IllegalArgumentException("descriptor can't be null");
        } else
        {
            useController(numPorts, descriptor, 2, true);
            return;
        }
    }

    public abstract ControllerPortManager getControllerPortManager();

    public abstract Cursor createCursor(Image image, int i, int j);

    public abstract void setCursor(Cursor cursor);

    /**
     * @deprecated Method addControllerListener is deprecated
     */

    public void addControllerListener(int index, ControllerListener listener)
    {
        ControllerPortManager manager = getControllerPortManager();
        ControllerPort port = manager.getPort(index);
        if(port != null)
            port.addControllerListener(listener);
    }

    /**
     * @deprecated Method removeControllerListener is deprecated
     */

    public void removeControllerListener(int index, ControllerListener listener)
    {
        ControllerPortManager manager = getControllerPortManager();
        ControllerPort port = manager.getPort(index);
        if(port != null)
            port.removeControllerListener(listener);
    }

    public abstract KeyboardDevice getKeyboardDevice();

    public abstract AudioPlayer getMpegAudioPlayer();

    public void igwSetGraphicMode(int i)
    {
    }

    public void igwSetInfo(int i, String s, String s1, int j, int k, String s2)
    {
    }

    public void igwFinalize()
    {
    }

    public void igwSetAudio(int i, int j)
    {
    }

    public int igwGetSound()
    {
        return 0;
    }

    public int igwGetEffect()
    {
        return 0;
    }

    public boolean igwInitializeGraphic()
    {
        return true;
    }

    public void igwFinalizeGraphic()
    {
    }

    public void igwDraw()
    {
    }

    public boolean igwIsNeedDraw()
    {
        return false;
    }

    public void igwSetGameInfo()
    {
    }

    public void igwLogin(String s, String s1, long l)
    {
    }

    public void igwLogout()
    {
    }

    public void igwChangeUserDetailInfo(String s, int i, String s1, String s2)
    {
    }

    public void igwChangeUserDetailInfo(char ac[], int i, String s, String s1)
    {
    }

    public void igwChangeLocation(String s, String s1, String s2, String s3, String s4)
    {
    }

    public void igwCommunity(String s)
    {
    }

    public boolean igwMultiFunction(int type, String arg)
    {
        return false;
    }

    public void igwSetEnable(boolean flag)
    {
    }

    public boolean igwGetEnable()
    {
        return false;
    }

    static {
        // setting this true causes window events not to get sent on Linux if you run from inside Eclipse
        GLProfile.initSingleton( false );
    }
    
    private static final String OS_WINDOWS = "backstage.runtime.KeelRuntimeWindowsImpl";
    private static final String OS_MACOSX = "backstage.runtime.KeelRuntimeMacOSXImpl";
    private static final String OS_UNKNOWN = "unknown";
    private static String ostype = "unknown";
    private static KeelRuntime runtime = null;
    static ResourceBundle resources;
    private KeyListener keyListener;
    private MouseListener mouseListener;
    private InputMethodListener inputMethodListener;
    protected Application application;
    ApplicationClassLoader classLoader;
    static boolean restartRequested;

}
